package org.javaymw.springboot.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.javaymw.springboot.dto.OrganizationDto;
import org.javaymw.springboot.dto.TreeOrganizationDto;
import org.javaymw.springboot.entity.OrganizationEntity;
import org.javaymw.springboot.mapper.OrganizationMapper;
import org.javaymw.springboot.service.OrganizationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: zhaoxinguo
 * @Date: 2018/11/2 17:15
 * @Description:
 */
@Service
@Transactional
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, OrganizationEntity> implements OrganizationService {

    @Autowired
    private OrganizationMapper organizationMapper;

    @Override
    public Page<OrganizationDto> getOrganizationByPage(int pageNum, int pageSize, Long parentId) {
        PageHelper.startPage(pageNum, pageSize);
        Map<String, Object> columnMap = new HashMap<String, Object>(16);
        if (!StringUtils.isEmpty(parentId)) {
            columnMap.put("parent_id", parentId);
        }
        Page<OrganizationEntity> organizationEntities = organizationMapper.findByPage(columnMap);
        if (CollectionUtils.isEmpty(organizationEntities)) {
            return null;
        }
        Page<OrganizationDto> organizationDtos = new Page<OrganizationDto>();
        for (OrganizationEntity organizationEntity : organizationEntities) {
            OrganizationDto organizationDto = new OrganizationDto();
            BeanUtils.copyProperties(organizationEntity, organizationDto);
            organizationDtos.add(organizationDto);
        }
        return toDto(organizationEntities, organizationDtos);
    }

    @Override
    public List<OrganizationDto> findOrganizationList() {
        Wrapper<OrganizationEntity> wrapper = new EntityWrapper<>();
        List<OrganizationEntity> organizationEntities = organizationMapper.selectList(wrapper);
        if (organizationEntities == null) {
            return null;
        }
        List<OrganizationDto> organizationDtos = new ArrayList<>(organizationEntities.size());
        organizationEntities.forEach(organizationEntity -> {
            OrganizationDto organizationDto = new OrganizationDto();
            BeanUtils.copyProperties(organizationEntity, organizationDto);
            organizationDtos.add(organizationDto);
        });
        return organizationDtos;
    }

    @Override
    public List<TreeOrganizationDto> findOrganizationByTree() {
        Wrapper<OrganizationEntity> wrapper = new EntityWrapper<OrganizationEntity>();
        List<OrganizationEntity> organizationEntities = organizationMapper.selectList(wrapper);
        if (organizationEntities.isEmpty()) {
            return null;
        }
        return getTreeOrganizationDtos(organizationEntities);
    }

    private List<TreeOrganizationDto> getTreeOrganizationDtos(List<OrganizationEntity> organizationEntities) {
        /**
         * List to Tree
         */
        List<TreeOrganizationDto> organizationDtos = new ArrayList<>();
        for (OrganizationEntity organizationEntity : organizationEntities) {
            TreeOrganizationDto treeOrganizationDto = new TreeOrganizationDto();
            BeanUtils.copyProperties(organizationEntity, treeOrganizationDto);
            organizationDtos.add(treeOrganizationDto);
        }
        List<TreeOrganizationDto> treeOrganizationDtos = new ArrayList<>();
        for (TreeOrganizationDto treeOrganizationDto1 : organizationDtos) {
            boolean mark = false;
            for (TreeOrganizationDto treeOrganizationDto2 : organizationDtos) {
                if (treeOrganizationDto1.getParentId() != null && treeOrganizationDto1.getParentId().equals(treeOrganizationDto2.getId())) {
                    mark = true;
                    if (treeOrganizationDto2.getChildren() == null) {
                        treeOrganizationDto2.setChildren(new ArrayList<>());
                    }
                    treeOrganizationDto2.getChildren().add(treeOrganizationDto1);
                    break;
                }
            }
            if (!mark) {
                treeOrganizationDtos.add(treeOrganizationDto1);
            }
        }
        return treeOrganizationDtos;
    }

    private Page<OrganizationDto> toDto(Page<OrganizationEntity> organizationEntities, Page<OrganizationDto> organizationDtos) {
        BeanUtils.copyProperties(organizationEntities, organizationDtos);
        return organizationDtos;
    }
}
